class GRs:
    def __init__(self):
        self.gr = [0 for i in range(16)]
    def reset(self):
        for i in range(16):
            self.gr[i] = 0
                    
    def write_gr64(self, value, un):
        self.gr[un] = value & 0xFFFFFFFFFFFFFFFF;
        
    def write_gr32(self, value, vn):
        if vn & 1 == 1:
            self.gr[vn >> 1] = (self.gr[vn >> 1] & 0xFFFFFFFF) | ( (value << 32) & 0xFFFFFFFF00000000)
        else:
            self.gr[vn >> 1] = (self.gr[vn >> 1] & 0xFFFFFFFF00000000) | ( (value) & 0xFFFFFFFF)
                    
    def write_gr16(self, value, wn):
        if wn & 3 == 0:
            self.gr[wn >> 2] = (self.gr[wn >> 2] & 0xFFFFFFFFFFFF0000) | ( (value) & 0xFFFF)
        elif wn & 3 == 1:
            self.gr[wn >> 2] = (self.gr[wn >> 2] & 0xFFFFFFFF0000FFFF) | ( (value << 16) & 0xFFFF0000)
        elif wn & 3 == 2:
            self.gr[wn >> 2] = (self.gr[wn >> 2] & 0xFFFF0000FFFFFFFF) | ( (value << 32) & 0xFFFF00000000)
        elif wn & 3 == 3:
            self.gr[wn >> 2] = (self.gr[wn >> 2] & 0x0000FFFFFFFFFFFF) | ( (value << 48) & 0xFFFF000000000000)
            
    def read_gr64(self, un):
        return self.gr[un]
    
    def read_gr32(self, vn):
        if vn & 1 == 0:
            return self.gr[(vn >> 1)] & 0xFFFFFFFF
        else:
            return (self.gr[(vn >> 1)] >> 32) & 0xFFFFFFFF
        
    def read_gr16(self, wn):
        if wn & 3 == 0:
            return (self.gr[wn >> 2]) & 0xFFFF
        elif wn & 3 == 1:
            return (self.gr[wn >> 2] >> 16) & 0xFFFF
        elif wn & 3 == 2:
            return (self.gr[wn >> 2] >> 32) & 0xFFFF
        elif wn & 3 == 3: 
            return (self.gr[wn >> 2] >> 48) & 0xFFFF
        
    def list_all(self):
        print "------------------------------"
        for i in range(15, -1, -1):
            print "%4X\t%04X_%04X_%04X_%04X" % (i, self.read_gr16(i * 4 + 3), self.read_gr16(i * 4 + 2), self.read_gr16(i * 4 + 1), self.read_gr16(i * 4))
        print "------------------------------"
        
# special Registers
class SRs:
    """CCR:|N|Z|V|C|"""
    
    def __init__(self):
        self.ccr = 0
        self.pc = 0
        self.sp = 0
        self.y = 0
    
    def setY32(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFFFFFFFFFF00000000 ) | (new_y & 0xFFFFFFFF)

    def setY64(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFF0000000000000000 ) | (new_y & 0xFFFFFFFFFFFFFFFF)

    def setY128(self, new_y):
        self.y = new_y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    
    def setYH16(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF ) | ((new_y << 16) & 0xFFFF)
    
    def setYL16(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 ) | ((new_y) & 0xFFFF)
        
    def setYH32(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF ) | ((new_y << 32) & 0xFFFFFFFF)
    
    def setYL32(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 ) | ((new_y) & 0xFFFFFFFF)
        
    def setYH64(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF ) | ((new_y << 64) & 0xFFFFFFFFFFFFFFFF)
    
    def setYL64(self, new_y):
        self.y = (self.y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 ) | ((new_y) & 0xFFFFFFFFFFFFFFFF)
        
    def getY128(self):
        return self.y
    
    def getY64(self):
        return self.y & 0xFFFFffffFFFFffff
    
    def getY32(self):
        return self.y & 0xFFFFffff
    
    def getYH64(self):
        return (self.y >> 64) & 0xFFFFffffFFFFffff
    
    def getYH32(self):
        return (self.y >> 32) & 0xFFFFffff

    def getYH16(self):
        return (self.y >> 16) & 0xFFFF   
    
    def getYL64(self):
        return (self.y) & 0xFFFFffffFFFFffff
    
    def getYL32(self):
        return (self.y) & 0xFFFFffff

    def getYL16(self):
        return (self.y) & 0xFFFF
    
        
    def setSP16(self, sp):
        self.sp = (self.sp & 0xFFFF0000) | (sp & 0xFFFF)

    def setSP32(self, sp):
        self.sp = sp & 0xFFFFFFFF
        
    def getSP16(self):
        return self.sp & 0xFFFF
    
    def getSP32(self):
        return self.sp

    def setPC16(self, new_pc):
        self.pc = (self.pc & 0xFFFFFFFFFFFF0000) | (new_pc & 0xFFFF)
    
    def setPC32(self, new_pc):
        self.pc = (self.pc & 0xFFFFFFFF00000000) | (new_pc & 0xFFFFFFFF)

    def setPC64(self, new_pc):
        self.pc = (new_pc) & 0xFFFFFFFFFFFFFFFF
    
    def setPC(self, new_pc):
        self.pc = (new_pc) & 0xFFFFFFFFFFFFFFFF
    
    def getPC(self):
        return self.pc
    
    def getPC64(self):
        return self.pc
    
    def getPC32(self):
        return self.pc & 0xFFFFFFFF
    
    def getPC16(self):
        return self.pc & 0xFFFF
        
    def setCCR_N(self, bit):
        if bit == 1:
            self.ccr = (self.ccr | 0x8)
        else:
            self.ccr = (self.ccr & ~0x8)
        
    def setCCR_Z(self, bit):
        if bit == 1:
            self.ccr = (self.ccr | 0x4)
        else:
            self.ccr = (self.ccr & ~0x4)
        
    def setCCR_V(self, bit):
        if bit == 1:
            self.ccr = (self.ccr | 0x2)
        else:
            self.ccr = (self.ccr & ~0x2)
        
    def setCCR_C(self, bit):
        if bit == 1:
            self.ccr = (self.ccr | 0x1)
        else:
            self.ccr = (self.ccr & ~0x1)
    
    def getCCR_N(self):
        return ((self.ccr & 0x8) != 0)
        
    def getCCR_Z(self):
        return ((self.ccr & 0x4) != 0)
        
    def getCCR_V(self):
        return ((self.ccr & 0x2) != 0)
        
    def getCCR_C(self):
        return ((self.ccr & 0x1) != 0)
    
    def getCCR(self):
        return ((self.ccr & 0xF))
    
    def setCCR(self, ccr):
        self.ccr = ccr & 0xF
